home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / FinderFlocks / FinderFun / Exceptions.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  3.9 KB  |  141 lines  |  [TEXT/MMCC]

  1. /*============================================================
  2.     Exceptions.h
  3.     
  4.     greggor@apple.com
  5. ============================================================*/
  6. #ifndef __EXCEPTIONS__
  7. #define __EXCEPTIONS__
  8. #define Exceptions_h
  9.  
  10. #ifndef __RESOURCES__
  11. #include <Resources.h>
  12. #endif
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. #include <setjmp.h>
  19.  
  20. //
  21. // Our error codes
  22. //
  23. const OSErr ePointerNil                = -110;
  24. const OSErr eGeneralErr                = -1;
  25. const OSErr eAssertionFailure        = -30000;
  26. const OSErr eRequirementNotMet        = -30001;
  27. const OSErr eValueOutOfRange        = -30002;
  28. const OSErr eIndexOutOfRange        = -30003;
  29. const OSErr eLinksCorrupt            = -30004;
  30. const OSErr eDataCorrupt            = -30005;
  31. const OSErr eWrongDataType            = -30006;
  32.  
  33. //
  34. // Constants used by the failure class
  35. //
  36. const long kMagicFailID                = 'fail';
  37.  
  38. const long kTryFrameOnFailureStack    = 0x0001;
  39. const long kExceptionThrown            = 0x0002;
  40. const long kTryInProgress            = 0x0004;
  41. const long kTrySucceeded            = 0x0008;
  42. const long kResignalingFailure        = 0x0010;
  43. const long kTryBlockHasBeenSetup    = 0x0100;
  44.  
  45. //
  46. // Failure class
  47. //
  48. class TException
  49. {
  50. public:
  51.     TException*                fNext;
  52.     OSErr                    fError;
  53.     long                    fFlags;
  54.     jmp_buf                    fEnv;
  55.     long                    fMagicFailID;
  56.  
  57.                             TException() : fNext(nil), fError(noErr), fFlags(0), fMagicFailID(kMagicFailID) {};
  58.     Boolean                    Setup();
  59.     void                    TearDown();
  60.     Boolean                    BeginTry();
  61.     OSErr                    ExceptionError()        { return fError; };
  62. };
  63.  
  64. //
  65. //  try / catch macros
  66. //
  67. //    Formerly, I used the result of setjmp to set status bits;
  68. //    however, that's not working in MetroWerks.  My guess is that
  69. //    there is some confusion over sizeof(int), but I'm not sure.
  70. //    Therefore, I'm just going to assume that the second time
  71. //    fi.Setup executes, we're failing.
  72. //
  73. #define Try            TException fi; setjmp(fi.fEnv); if(fi.Setup()) while(fi.BeginTry())
  74. #define Catch(err)    else if((err = fi.ExceptionError()) != noErr)
  75.  
  76. typedef void (*NotifyFailureProc)(OSErr err);
  77.  
  78. //
  79. // Globals:
  80. //
  81. extern TException*            gExceptionStack;
  82.  
  83. //
  84. // Prototypes
  85. //
  86. void                        Throw(OSErr theErr);
  87.  
  88. void                        SetExceptionNotifyProc(NotifyFailureProc notifyProc);
  89. Boolean                        ExceptionNotifyProcInstalled(void);
  90. void                        NotifyFailure(OSErr err);
  91.  
  92. void                        MakeVariableNoRegister( void* foo );
  93.  
  94. //
  95. // You really shouldn't use this...  far better to say:
  96. //
  97. //        Catch(err)
  98. //        {
  99. //            Throw(err);
  100. //        }
  101. //
  102. #define ResignalFailure()            Throw(fi.ExceptionError());
  103.  
  104. //
  105. // This macro references the address of the specified local
  106. // variable; this will prevent the compiler from using the
  107. // variable as a register variable.
  108. //
  109. #define NOREGISTER(x)        ( MakeVariableNoRegister( (void*)(&(x)) ) )
  110.  
  111. //
  112. //    Convenience functions
  113. //
  114. inline void Fail()                            { Throw(eGeneralErr); }
  115. inline void FailErr(OSErr theErr)            { if(theErr != noErr) Throw(theErr); }
  116. inline void FailResError()                    { FailErr(ResError()); }
  117. inline void FailMemError()                    { FailErr(MemError()); }
  118. inline void FailNil(void* ptr)                { if(ptr == nil) Throw(ePointerNil); }
  119. inline void FailResErrorOrNil(void* ptr)    { FailResError(); FailNil(ptr); }
  120. inline void FailMemErrorOrNil(void* ptr)    { FailMemError(); FailNil(ptr); }
  121.  
  122. //
  123. // Requirements
  124. //
  125. inline void Require(Boolean truth)            { if( !(truth) ) Throw(eRequirementNotMet); }
  126. inline void RequirePtrValid(void* p)        { if( (p == nil) || (((long)(p) & 1) != 0) ) Throw(eRequirementNotMet); }
  127. inline void RequireHandleValid(Handle h)    { RequirePtrValid((void*)(h)); RequirePtrValid((void*)(*h)); }
  128.  
  129. //
  130. // Requirements must always be met, but Assertions can be removed in non-debug builds
  131. // as they are statements that are ASSUMED to always be true
  132. //
  133. inline void Assert(Boolean truth)            { if( !(truth) ) Throw(eAssertionFailure); }
  134. inline void AssertPtrValid(void* p)            { if( (p == nil) || (((long)(p) & 1) != 0) ) Throw(eAssertionFailure); }
  135. inline void AssertHandleValid(void** h)        { AssertPtrValid((void*)h); AssertPtrValid(*h); }
  136.  
  137. #define ASSERT(x) Assert(x)
  138. #define REQUIRE(x) Require(x)
  139.  
  140. #endif
  141.